using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using SharpPieces.Web.JQuery.Design;
using System.Web;
using System.Security.Permissions;
using System.Drawing.Design;

[assembly: WebResource("SharpPieces.Web.JQuery.PanelExtender.shadedborder.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.JQuery.PanelExtender.ui.core.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.JQuery.PanelExtender.ui.draggable.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.JQuery.PanelExtender.ui.droppable.js", "text/javascript")]

namespace SharpPieces.Web.JQuery
{

    /// <summary>
    /// Represents a Panel extender containing various plugins.
    /// </summary>
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [Designer(typeof(PanelExtenderDesigner)), Description("Panel extender containing various plugins."), DefaultProperty("TargetControlID")]
    [ToolboxData("<{0}:PanelExtender runat=\"server\"></{0}:PanelExtender>"), PersistChildren(false), ParseChildren(true), Themeable(true)]
    [ToolboxBitmap(typeof(PanelExtender), "PanelExtender.PanelExtender.bmp")]
    public class PanelExtender : BaseJQueryExtender
    {

        // Methods

        /// <summary>
        /// Gets the JQuery object properties.
        /// The key is the object property name.
        /// The value is the object property initial value.
        /// </summary>
        protected override IEnumerable<KeyValuePair<string, object>> GetJQueryObjectProperties()
        {
            yield break;
        }

        /// <summary>
        /// Gets the JQuery object events.
        /// The key is the object event name.
        /// The value is the object event handler.
        /// </summary>
        /// <returns></returns>
        protected override IEnumerable<KeyValuePair<string, string>> GetJQueryObjectEvents()
        {
            yield break;
        }

        /// <summary>
        /// Gets the JQuery script references.
        /// </summary>
        /// <returns></returns>
        protected override IEnumerable<ScriptReference> GetJQueryScriptReferences()
        {
#if DEBUG
            if (this.ShadedBorder.Enabled)
            {
                yield return new ScriptReference(
                    this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.shadedborder.js"),
                    typeof(PanelExtender).Assembly.FullName);
            }

            if (this.JQueryUI.Enabled)
            {
                yield return new ScriptReference(
                    this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.ui.core.js"),
                    typeof(PanelExtender).Assembly.FullName);
                yield return new ScriptReference(
                    this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.ui.draggable.js"),
                    typeof(PanelExtender).Assembly.FullName);
                yield return new ScriptReference(
                    this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.ui.droppable.js"),
                    typeof(PanelExtender).Assembly.FullName);
            }
#else
            if (this.ShadedBorder.Enabled)
            {
                yield return new ScriptReference(
                    this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.shadedborder.js"), 
                    typeof(PanelExtender).Assembly.FullName);
            }

            if (this.JQueryUI.Enabled)
            {
                yield return new ScriptReference(
                    this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.ui.core.js"),
                    typeof(PanelExtender).Assembly.FullName);
                yield return new ScriptReference(
                        this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.ui.draggable.js"),
                        typeof(PanelExtender).Assembly.FullName);
                yield return new ScriptReference(
                        this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.JQuery.PanelExtender.ui.droppable.js"),
                        typeof(PanelExtender).Assembly.FullName);
            }
#endif
        }

        /// <summary>
        /// Gets the client initialization scripts.
        /// The key is the script name and the value is the script.
        /// </summary>
        /// <returns></returns>
        /// <value>The client initialization scripts.</value>
        protected IEnumerable<KeyValuePair<string, string>> GetClientScriptInitializations()
        {
            Panel target = this.ResolveTargetControl<Panel>();

            if (this.ShadedBorder.Enabled)
            {
                Dictionary<string, string> options = new Dictionary<string, string>();

                // corner length ShadedBorder
                options["id"] = string.Format("'{0}'", this.ID);

                // corner length ShadedBorder
                options["corner"] = this.ShadedBorder.CornerLength.ToString();

                // border width ShadedBorder
                options["border"] = this.ShadedBorder.BorderWidth.ToString();

                // border opacity ShadedBorder
                options["borderOpacity"] = this.ShadedBorder.BorderOpacity.ToString();

                // shadow width ShadedBorder
                options["shadow"] = this.ShadedBorder.ShadowWidth.ToString();

                // inner color ShadedBorder
                options["sbinner"] = string.Format("'{0}'", ColorTranslator.ToHtml(this.ShadedBorder.InnerColor));

                // shadow color ShadedBorder
                options["sbshadow"] = string.Format("'{0}'", ColorTranslator.ToHtml(this.ShadedBorder.ShadowColor));

                // border color ShadedBorder
                options["sbborder"] = string.Format("'{0}'", ColorTranslator.ToHtml(this.ShadedBorder.BorderColor));

                //// inner image ShadedBorder
                //if (!string.IsNullOrEmpty(this.InnerImageShadedBorder))
                //{
                //    options["sbinnerimage"] = string.Format("'{0}'", VirtualPathUtility.ToAbsolute(this.InnerImageShadedBorder));
                //}

                // corner length ShadedBorder
                string edges = "";
                if ((EdgesShadedBorder.Top & this.ShadedBorder.Edges) == EdgesShadedBorder.Top)
                {
                    edges += "t";
                }
                if ((EdgesShadedBorder.Right & this.ShadedBorder.Edges) == EdgesShadedBorder.Right)
                {
                    edges += "r";
                }
                if ((EdgesShadedBorder.Left & this.ShadedBorder.Edges) == EdgesShadedBorder.Left)
                {
                    edges += "l";
                }
                if ((EdgesShadedBorder.Bottom & this.ShadedBorder.Edges) == EdgesShadedBorder.Bottom)
                {
                    edges += "b";
                }
                if (0 < edges.Length)
                {
                    options["edges"] = string.Format("'{0}'", edges);
                }

                yield return new KeyValuePair<string, string>(
                    string.Format("{0}InitPanelExtender", this.TargetControlID),
                    string.Format(
                        "<script type=\"text/javascript\">RUZEE.ShadedBorder.create({1}).render('{0}');</script>",
                        target.ClientID,
                        BaseJQueryExtender.OptionListToJS(options))
                    );
            }

            if (this.JQueryUI.Enabled)
            {
                yield return new KeyValuePair<string, string>(
                    string.Format("{0}InitPanelDraggable", this.TargetControlID),
                    string.Format(
                        "<script type=\"text/javascript\">jQuery(\"#{0}\").draggable();</script>",
                        target.ClientID)
                    );
            }

            yield break;
        }

        /// <summary>
        /// Gets the control style references.
        /// </summary>
        /// <returns></returns>
        /// <value>The control style references.</value>
        protected override IEnumerable<string> GetClientStyleReferences()
        {
            yield break;
        }

        // Properties

        /// <summary>
        /// Gets or sets the target control ID.
        /// </summary>
        /// <value>The target control ID.</value>
        [TypeConverter(typeof(PanelControlConverter))]
        public override string TargetControlID
        {
            get { return base.TargetControlID; }
            set { base.TargetControlID = value; }
        }

        /// <summary>
        /// Gets or sets the configuration for the ShadedBorder plugin (Steffen Rusitschka).
        /// </summary>
        /// <value>The configuration for the ShadedBorder plugin (Steffen Rusitschka).</value>
        [Description("The configuration for the ShadedBorder plugin (Steffen Rusitschka)."), Category("Plugins"), DefaultValue((string)null), MergableProperty(false)]
        [PersistenceMode(PersistenceMode.InnerProperty), Themeable(false)]
        public virtual ShadedBorder ShadedBorder
        {
            get
            {
                if (null == this.ViewState["ShadedBorder"])
                {
                    ShadedBorder sb = new ShadedBorder();
                    if (this.EnableViewState)
                    {
                        sb.TrackViewState();
                    }
                    this.ViewState["ShadedBorder"] = sb;
                }
                return (ShadedBorder)this.ViewState["ShadedBorder"];
            }
            set
            {
                if ((null != value) && this.EnableViewState)
                {
                    value.TrackViewState();
                }
                this.ViewState["ShadedBorder"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the configuration for the JQueryUI plugin.
        /// </summary>
        /// <value>The configuration for the JQueryUI plugin.</value>
        [Description("The configuration for the JQueryUI plugin"), Category("Plugins"), DefaultValue((string)null), MergableProperty(false), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty), Themeable(false)]
        public virtual JQueryUI JQueryUI
        {
            get
            {
                if (null == this.ViewState["JQueryUI"])
                {
                    JQueryUI jqui = new JQueryUI();
                    if (this.EnableViewState)
                    {
                        jqui.TrackViewState();
                    }
                    this.ViewState["JQueryUI"] = jqui;
                }
                return (JQueryUI)this.ViewState["JQueryUI"];
            }
            set
            {
                if ((null != value) && this.EnableViewState)
                {
                    value.TrackViewState();
                }
                this.ViewState["JQueryUI"] = value;
            }
        }

    }


    /// <summary>
    /// Represents a ShadedBorder plugin implementation.
    /// </summary>
    [Serializable]
    [TypeConverter(typeof(ExpandableObjectConverter)), DefaultProperty("Enabled")]
    public class ShadedBorder : IStateManager
    {

        // Fields

        private bool tracks;
        private DirtyFlags dirtyFlags = DirtyFlags.None;
        private bool enabled = false;
        private EdgesShadedBorder edges = EdgesShadedBorder.All;
        private Color innerColor = Color.Gray;
        private int borderWidth = 0;
        private float borderOpacity = 1;
        private Color borderColor = Color.DarkGray;
        private int cornerLength = 0;
        private int shadowWidth = 0;
        private Color shadowColor = Color.LightGray;


        // Methods

        /// <summary>
        /// When implemented by a class, gets a value indicating whether a server control is tracking its view state changes.
        /// </summary>
        /// <value></value>
        /// <returns>true if a server control is tracking its view state changes; otherwise, false.</returns>
        internal bool IsTrackingViewState
        {
            get { return this.tracks; }
        }

        /// <summary>
        /// When implemented by a class, loads the server control's previously saved view state to the control.
        /// </summary>
        /// <param name="state">An <see cref="T:System.Object"></see> that contains the saved view state values for the control.</param>
        internal virtual void LoadViewState(object state)
        {
            if (null != state)
            {
                object[] s = state as object[];
                if (null != s[0])
                {
                    this.Enabled = (bool)s[0];
                }
                if (null != s[1])
                {
                    this.Edges = (EdgesShadedBorder)s[1];
                }
                if (null != s[2])
                {
                    this.InnerColor = (Color)s[2];
                }
                if (null != s[3])
                {
                    this.BorderWidth = (int)s[3];
                }
                if (null != s[4])
                {
                    this.BorderOpacity = (float)s[4];
                }
                if (null != s[5])
                {
                    this.BorderColor = (Color)s[5];
                }
                if (null != s[6])
                {
                    this.CornerLength = (int)s[6];
                }
                if (null != s[7])
                {
                    this.ShadowWidth = (int)s[7];
                }
                if (null != s[8])
                {
                    this.ShadowColor = (Color)s[8];
                }
            }
        }

        /// <summary>
        /// When implemented by a class, saves the changes to a server control's view state to an <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Object"></see> that contains the view state changes.
        /// </returns>
        internal virtual object SaveViewState()
        {
            object[] state = new object[9];

            state[0] = ((this.dirtyFlags & DirtyFlags.Enabled) == DirtyFlags.Enabled) ? (object)this.Enabled : null;
            state[1] = ((this.dirtyFlags & DirtyFlags.Edges) == DirtyFlags.Edges) ? (object)this.Edges : (object)null;
            state[2] = ((this.dirtyFlags & DirtyFlags.InnerColor) == DirtyFlags.InnerColor) ? (object)this.InnerColor : (object)null;
            state[3] = ((this.dirtyFlags & DirtyFlags.BorderWidth) == DirtyFlags.BorderWidth) ? (object)this.BorderWidth : (object)null;
            state[4] = ((this.dirtyFlags & DirtyFlags.BorderOpacity) == DirtyFlags.BorderOpacity) ? (object)this.BorderOpacity : (object)null;
            state[5] = ((this.dirtyFlags & DirtyFlags.BorderColor) == DirtyFlags.BorderColor) ? (object)this.BorderColor : null;
            state[6] = ((this.dirtyFlags & DirtyFlags.CornerLength) == DirtyFlags.CornerLength) ? (object)this.CornerLength : (object)null;
            state[7] = ((this.dirtyFlags & DirtyFlags.ShadowWidth) == DirtyFlags.ShadowWidth) ? (object)this.ShadowWidth : (object)null;
            state[8] = ((this.dirtyFlags & DirtyFlags.ShadowColor) == DirtyFlags.ShadowColor) ? (object)this.ShadowColor : (object)null;

            return state;
        }

        /// <summary>
        /// When implemented by a class, instructs the server control to track changes to its view state.
        /// </summary>
        internal void TrackViewState()
        {
            this.tracks = true;
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override string ToString()
        {
            return string.Empty;
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            if ((null == obj) || (typeof(ShadedBorder) != obj.GetType()))
            {
                return false;
            }

            ShadedBorder compared = (ShadedBorder)obj;
            return
                (this.Enabled == compared.Enabled) &&
                (this.Edges == compared.Edges) &&
                (this.InnerColor == compared.InnerColor) &&
                (this.BorderWidth == compared.BorderWidth) &&
                (this.BorderOpacity == compared.BorderOpacity) &&
                (this.BorderColor == compared.BorderColor) &&
                (this.CornerLength == compared.CornerLength) &&
                (this.ShadowWidth == compared.ShadowWidth) &&
                (this.ShadowColor == compared.ShadowColor);
        }

        /// <summary>
        /// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use in hashing algorithms and data structures like a hash table.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }


        // Properties

        /// <summary>
        /// Gets or sets a value indicating whether to enable this plugin.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this plugin should be enabled; otherwise, <c>false</c>.
        /// </value>
        [Description("Indicates whether to enable this plugin."), DefaultValue(false), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual bool Enabled
        {
            get { return this.enabled; }
            set
            {
                this.enabled = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.Enabled;
                }
            }
        }

        /// <summary>
        /// Gets or sets the edges.
        /// </summary>
        /// <value>The edges.</value>
        [Browsable(false)]
        public virtual EdgesShadedBorder Edges
        {
            get { return this.edges; }
            set
            {
                this.edges = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.Edges;
                }
            }
        }

        /// <summary>
        /// Gets or sets the inner color.
        /// </summary>
        /// <value>The inner color in pixels.</value>
        [Description("The inner color in pixels."), DefaultValue(typeof(Color), "Gray"), TypeConverter(typeof(WebColorConverter)), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual Color InnerColor
        {
            get { return this.innerColor; }
            set
            {
                this.innerColor = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.InnerColor;
                }
            }
        }

        /// <summary>
        /// Gets or sets the border width in pixels.
        /// </summary>
        /// <value>The rounded border width in pixels.</value>
        [Description("The rounded border width in pixels."), DefaultValue((int)0), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual int BorderWidth
        {
            get { return this.borderWidth; }
            set
            {
                this.borderWidth = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.BorderWidth;
                }
            }
        }

        /// <summary>
        /// Gets or sets the border opacity (value between 0 and 1).
        /// </summary>
        /// <value>The border opacity (value between 0 and 1).</value>
        [Description("The border opacity (value between 0 and 1)."), DefaultValue((float)1), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual float BorderOpacity
        {
            get { return this.borderOpacity; }
            set
            {
                this.borderOpacity = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.BorderOpacity;
                }
            }
        }

        /// <summary>
        /// Gets or sets the border color.
        /// </summary>
        /// <value>The border color in pixels.</value>
        [Description("The border color in pixels."), DefaultValue(typeof(Color), "DarkGray"), TypeConverter(typeof(WebColorConverter)), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual Color BorderColor
        {
            get { return this.borderColor; }
            set
            {
                this.borderColor = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.BorderColor;
                }
            }
        }

        /// <summary>
        /// Gets or sets the corner length in pixels.
        /// </summary>
        /// <value>The corner length in pixels.</value>
        [Description("The corner length."), DefaultValue(0), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual int CornerLength
        {
            get { return this.cornerLength; }
            set
            {
                this.cornerLength = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.CornerLength;
                }
            }
        }

        /// <summary>
        /// Gets or sets the shadow width in pixels.
        /// </summary>
        /// <value>The shadow width in pixels.</value>
        [Description("The shadow width in pixels."), DefaultValue(0), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual int ShadowWidth
        {
            get { return this.shadowWidth; }
            set
            {
                this.shadowWidth = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.ShadowWidth;
                }
            }
        }

        /// <summary>
        /// Gets or sets the shadow color.
        /// </summary>
        /// <value>The shadow color in pixels.</value>
        [Description("The shadow color in pixels."), DefaultValue(typeof(Color), "LightGray"), TypeConverter(typeof(WebColorConverter)), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual Color ShadowColor
        {
            get { return this.shadowColor; }
            set
            {
                this.shadowColor = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.ShadowColor;
                }
            }
        }

        // Nested Types

        private enum DirtyFlags
        {
            None = 0,
            Enabled = 1,
            Edges = 2,
            InnerColor = 4,
            BorderWidth = 8,
            BorderOpacity = 16,
            BorderColor = 32,
            CornerLength = 64,
            ShadowWidth = 128,
            ShadowColor = 256
        }

        #region IStateManager Members

        /// <summary>
        /// When implemented by a class, gets a value indicating whether a server control is tracking its view state changes.
        /// </summary>
        /// <value></value>
        /// <returns>true if a server control is tracking its view state changes; otherwise, false.</returns>
        bool IStateManager.IsTrackingViewState
        {
            get { return this.IsTrackingViewState; }
        }

        /// <summary>
        /// When implemented by a class, loads the server control's previously saved view state to the control.
        /// </summary>
        /// <param name="state">An <see cref="T:System.Object"></see> that contains the saved view state values for the control.</param>
        void IStateManager.LoadViewState(object state)
        {
            this.LoadViewState(state);
        }

        /// <summary>
        /// When implemented by a class, saves the changes to a server control's view state to an <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Object"></see> that contains the view state changes.
        /// </returns>
        object IStateManager.SaveViewState()
        {
            return this.SaveViewState();
        }

        /// <summary>
        /// When implemented by a class, instructs the server control to track changes to its view state.
        /// </summary>
        void IStateManager.TrackViewState()
        {
            this.TrackViewState();
        }

        #endregion

    }


    /// <summary>
    /// The Shaded Border edges types.
    /// </summary>
    public enum EdgesShadedBorder
    {
        Top = 1,
        Right = 2,
        Left = 4,
        Bottom = 8,
        All = Top + Right + Left + Bottom
    }


    /// <summary>
    /// Represents a JQueryUI plugin implementation.
    /// </summary>
    [Serializable]
    [TypeConverter(typeof(ExpandableObjectConverter)), DefaultProperty("Enabled")]
    public class JQueryUI : IStateManager
    {

        // Fields

        private bool tracks;
        private DirtyFlags dirtyFlags = DirtyFlags.None;
        private bool enabled = false;
        private bool dragDropable = false;


        // Methods

        /// <summary>
        /// When implemented by a class, gets a value indicating whether a server control is tracking its view state changes.
        /// </summary>
        /// <value></value>
        /// <returns>true if a server control is tracking its view state changes; otherwise, false.</returns>
        internal bool IsTrackingViewState
        {
            get { return this.tracks; }
        }

        /// <summary>
        /// When implemented by a class, loads the server control's previously saved view state to the control.
        /// </summary>
        /// <param name="state">An <see cref="T:System.Object"></see> that contains the saved view state values for the control.</param>
        internal virtual void LoadViewState(object state)
        {
            if (null != state)
            {
                object[] s = state as object[];
                if (null != s[0])
                {
                    this.Enabled = (bool)s[0];
                }
                if (null != s[1])
                {
                    this.DragDropable = (bool)s[1];
                }
            }
        }

        /// <summary>
        /// When implemented by a class, saves the changes to a server control's view state to an <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Object"></see> that contains the view state changes.
        /// </returns>
        internal virtual object SaveViewState()
        {
            object[] state = new object[2];

            state[0] = ((this.dirtyFlags & DirtyFlags.Enabled) == DirtyFlags.Enabled) ? (object)this.Enabled : null;
            state[1] = ((this.dirtyFlags & DirtyFlags.DragDropable) == DirtyFlags.DragDropable) ? (object)this.DragDropable : (object)null;

            return state;
        }

        /// <summary>
        /// When implemented by a class, instructs the server control to track changes to its view state.
        /// </summary>
        internal void TrackViewState()
        {
            this.tracks = true;
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override string ToString()
        {
            return string.Empty;
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            if ((null == obj) || (typeof(JQueryUI) != obj.GetType()))
            {
                return false;
            }

            JQueryUI compared = (JQueryUI)obj;
            return
                (this.Enabled == compared.Enabled) &&
                (this.DragDropable == compared.DragDropable);
        }

        /// <summary>
        /// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use in hashing algorithms and data structures like a hash table.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }


        // Properties

        /// <summary>
        /// Gets or sets a value indicating whether to enable this plugin.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this plugin should be enabled; otherwise, <c>false</c>.
        /// </value>
        [Description("Indicates whether to enable this plugin."), DefaultValue(false), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual bool Enabled
        {
            get { return this.enabled; }
            set
            {
                this.enabled = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.Enabled;
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to enable drag-drop for this plugin.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if drag-drop should be be enabled; otherwise, <c>false</c>.
        /// </value>
        [Description("Indicates whether to enable drag-drop."), DefaultValue(false), NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.Attribute), Themeable(true)]
        public virtual bool DragDropable
        {
            get { return this.dragDropable; }
            set
            {
                this.dragDropable = value;
                if ((this as IStateManager).IsTrackingViewState)
                {
                    this.dirtyFlags = this.dirtyFlags | DirtyFlags.DragDropable;
                }
            }
        }


        // Nested Types

        private enum DirtyFlags
        {
            None = 0,
            Enabled = 1,
            DragDropable = 2,
        }

        #region IStateManager Members

        /// <summary>
        /// When implemented by a class, gets a value indicating whether a server control is tracking its view state changes.
        /// </summary>
        /// <value></value>
        /// <returns>true if a server control is tracking its view state changes; otherwise, false.</returns>
        bool IStateManager.IsTrackingViewState
        {
            get { return this.IsTrackingViewState; }
        }

        /// <summary>
        /// When implemented by a class, loads the server control's previously saved view state to the control.
        /// </summary>
        /// <param name="state">An <see cref="T:System.Object"></see> that contains the saved view state values for the control.</param>
        void IStateManager.LoadViewState(object state)
        {
            this.LoadViewState(state);
        }

        /// <summary>
        /// When implemented by a class, saves the changes to a server control's view state to an <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Object"></see> that contains the view state changes.
        /// </returns>
        object IStateManager.SaveViewState()
        {
            return this.SaveViewState();
        }

        /// <summary>
        /// When implemented by a class, instructs the server control to track changes to its view state.
        /// </summary>
        void IStateManager.TrackViewState()
        {
            this.TrackViewState();
        }

        #endregion

    }


    /// <summary>
    /// Provides a type converter that retrieves a list of control IDs in the current 
    /// container, of the Panel type or convertible.
    /// </summary>
    internal class PanelControlConverter : ControlIDConverter
    {

        // Methods

        /// <summary>
        /// Returns a value indicating whether the control ID of the specified control is added to the <see cref="T:System.ComponentModel.TypeConverter.StandardValuesCollection"></see> that is returned by the <see cref="M:System.Web.UI.WebControls.ControlIDConverter.GetStandardValues(System.ComponentModel.ITypeDescriptorContext)"></see> method.
        /// </summary>
        /// <param name="control">The control instance to test for inclusion in the <see cref="T:System.ComponentModel.TypeConverter.StandardValuesCollection"></see>.</param>
        /// <returns>true in all cases.</returns>
        protected override bool FilterControl(Control control)
        {
            return typeof(Panel).IsInstanceOfType(control);
        }

    }

}
